/*
 * Multithread demo program.
 * Hebrew University OS course.
 *
 * Questions: os@cs.huji.ac.il
 */

#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>

////////////////////////////////////////////////////////////////////////
#ifdef __x86_64__
// code for 64 bit Intel arch

typedef unsigned long address_t;
#define JB_SP 6
#define JB_PC 7

//A translation required when using an address of a variable
//Use this as a black box in your code.
address_t translate_address(address_t addr)
{
    address_t ret;
    asm volatile("xor    %%fs:0x30,%0\n"
		"rol    $0x11,%0\n"
                 : "=g" (ret)
                 : "0" (addr));
    return ret;
}

#else
// code for 32 bit Intel arch

typedef unsigned int address_t;
#define JB_SP 4
#define JB_PC 5 

//A translation required when using an address of a variable
//Use this as a black box in your code.
address_t translate_address(address_t addr)
{
    address_t ret;
    asm volatile("xor    %%gs:0x18,%0\n"
		"rol    $0x9,%0\n"
                 : "=g" (ret)
                 : "0" (addr));
    return ret;
}

#endif

////////////////////////////////////////////////////////////////////////

#if 0
void setup()
{
    address_t sp, pc;
    
    sp = (address_t)stack1 + STACK_SIZE - sizeof(int); 
    pc = (address_t)f;
    
    sigsetjmp(jbuf[0],1);
    (jbuf[0]->__jmpbuf)[JB_SP] = translate_address(sp);
    (jbuf[0]->__jmpbuf)[JB_PC] = translate_address(pc);
    sigemptyset(&jbuf[0]->__saved_mask);     


    sp = (address_t)stack2 + STACK_SIZE - sizeof(int);
    pc = (address_t)g;
    
    sigsetjmp(jbuf[1],1);
    (jbuf[1]->__jmpbuf)[JB_SP] = translate_address(sp);
    (jbuf[1]->__jmpbuf)[JB_PC] = translate_address(pc);
    sigemptyset(&jbuf[1]->__saved_mask);         
}
#endif

